#include <iostream>
#include <stdbool.h>

#include <boost/circular_buffer.hpp>
#include <boost/thread.hpp>

//#include <qt4/QtGui/qapplication.h>
//#include <qt4/QtGui/QLabel>

#include "../inc/Beamformer.h"
#include "../inc/Echo.h"
#include "../inc/EchoBuffer.hxx"

//#include "EchoGUI.h"

using namespace std;
using namespace boost;

static EchoBuffer echoesBuffer;
static circular_buffer<vector<complex<double> > > beams0degBuffer;
static circular_buffer<vector<complex<double> > > beams10degBuffer;
static circular_buffer<vector<complex<double> > > beams20degBuffer;
static circular_buffer<vector<complex<double> > > beams30degBuffer;
static circular_buffer<vector<complex<double> > > beams40degBuffer;


void initBuffers(int echoBufferCapacity, int beamsBufferCapacity) {
    echoesBuffer = EchoBuffer(echoBufferCapacity);
    beams0degBuffer = circular_buffer<vector<complex<double> > >(beamsBufferCapacity);
    beams10degBuffer = circular_buffer<vector<complex<double> > >(beamsBufferCapacity);
    beams20degBuffer = circular_buffer<vector<complex<double> > >(beamsBufferCapacity);
    beams30degBuffer = circular_buffer<vector<complex<double> > >(beamsBufferCapacity);
    beams40degBuffer = circular_buffer<vector<complex<double> > >(beamsBufferCapacity);
}

void probing() {
    int rows = 8, samples = 2;
    while(true) {
        Echo echo(rows, samples);
        echoesBuffer.push_front(echo);
        cout << "ECHO_BUFFER size: " << echoesBuffer.size() << endl;
    }
}

void beamforming() {
    Beamformer beamformer0deg(0, 8, 100, 25);
    Beamformer beamformer10deg(10, 8, 100, 25);
    Beamformer beamformer20deg(20, 8, 100, 25);
    Beamformer beamformer30deg(30, 8, 100, 25);
    Beamformer beamformer40deg(40, 8, 100, 25);
    
    while(true) {
        if(!echoesBuffer.empty()) {
            Echo echo = echoesBuffer.back();
            echoesBuffer.pop_back();
            beams0degBuffer.push_front(beamformer0deg.formUsingDFT(echo));
            beams10degBuffer.push_front(beamformer10deg.formUsingDFT(echo));
            beams20degBuffer.push_front(beamformer20deg.formUsingDFT(echo));
            beams30degBuffer.push_front(beamformer30deg.formUsingDFT(echo));
            beams40degBuffer.push_front(beamformer40deg.formUsingDFT(echo));
            cout << "rozmiar bufora wiązek: " << beams0degBuffer.size() << endl;
        }
    }
}

void emptyBuffer() {
    sleep(1);
    while(true) {
        if(!beams0degBuffer.empty()) {
            beams0degBuffer.pop_back();
            cout << "opróżniam 0" << endl;
        }
        if(!beams10degBuffer.empty()) {
            beams10degBuffer.pop_back();
            cout << "opróżniam 10" << endl;
        }
        if(!beams20degBuffer.empty()) {
            beams20degBuffer.pop_back();
            cout << "opróżniam 20" << endl;
        }
        if(!beams30degBuffer.empty()) {
            beams30degBuffer.pop_back();
            cout << "opróżniam 30" << endl;
        }
        if(!beams40degBuffer.empty()) {
            beams40degBuffer.pop_back();
            cout << "opróżniam 40" << endl;
        }
    }
}

int main(int argc, char *argv[]) {


//    initBuffers(30, 10000);
    boost::thread probingThread(&probing);       
//    boost::thread beamformingThread(&beamforming);
//    boost::thread emptyBuffersThread(&emptyBuffer);
//    beamformingThread.join();
    probingThread.join();
//    QApplication app(argc, argv);
//    QButton toggleProbing("uruchom sondowanie");
//    toggleProbing.show();
//    QButton toggleBeamforming("uruchom formowanie wiązki");
//    toggleBeamforming.show();
    return 0;
}
